package com.yunyao.framework.audit;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yunyao.common.constant.enums.AuditStatusEnums;
import com.yunyao.common.constant.enums.DataDeletedStatus;
import com.yunyao.common.constant.enums.SupplyListStatus;
import com.yunyao.common.constant.enums.SupplyStatus;
import com.yunyao.common.core.BaseContext;
import com.yunyao.common.core.UserInfoRequest;
import com.yunyao.common.dto.audit.AuditFlowTypeEnums;
import com.yunyao.common.dto.audit.AuditResultEnums;
import com.yunyao.common.dto.audit.CreateAuditFlowDto;
import com.yunyao.common.exception.AuditException;
import com.yunyao.common.exception.BusinessException;
import com.yunyao.common.web.enums.ResultMsgEnum;
import com.yunyao.dao.model.BamuContractNodePay;
import com.yunyao.dao.model.BamuPoPrePayment;
import com.yunyao.dao.model.BamuPoSupply;
import com.yunyao.dao.model.BamuPoSupplyMaterial;
import com.yunyao.dao.model.BamuPurchaseApply;
import com.yunyao.dao.model.BamuPurchaseApplyMaterial;
import com.yunyao.dao.model.BamuPurchaseConsignee;
import com.yunyao.dao.model.BamuPurchaseContract;
import com.yunyao.dao.model.BamuReconciliation;
import com.yunyao.dao.model.BamuReconciliationOrder;
import com.yunyao.dao.model.BamuReconciliationOrderMaterial;
import com.yunyao.dao.model.BamuSaleContract;
import com.yunyao.dao.model.BamuSoPrePayment;
import com.yunyao.dao.model.BamuSoSupply;
import com.yunyao.dao.model.BamuSoSupplyMaterial;
import com.yunyao.dao.model.BamuSpReconciliation;
import com.yunyao.dao.model.BamuSpReconciliationOrder;
import com.yunyao.dao.model.BamuSupplyApply;
import com.yunyao.dao.model.BamuSupplyApplyMaterial;
import com.yunyao.dao.model.BamuSupplyConsignee;
import com.yunyao.dao.service.bamu.IBamuPoPrePaymentService;
import com.yunyao.dao.service.bamu.IBamuPoSupplyMaterialService;
import com.yunyao.dao.service.bamu.IBamuPoSupplyService;
import com.yunyao.dao.service.bamu.IBamuPurchaseApplyMaterialService;
import com.yunyao.dao.service.bamu.IBamuPurchaseApplyService;
import com.yunyao.dao.service.bamu.IBamuPurchaseConsigneeService;
import com.yunyao.dao.service.bamu.IBamuPurchaseContractService;
import com.yunyao.dao.service.bamu.IBamuReconciliationOrderMaterialService;
import com.yunyao.dao.service.bamu.IBamuReconciliationOrderService;
import com.yunyao.dao.service.bamu.IBamuReconciliationService;
import com.yunyao.dao.service.bamu.IBamuSaleContractService;
import com.yunyao.dao.service.bamu.IBamuSoPrePaymentService;
import com.yunyao.dao.service.bamu.IBamuSoSupplyMaterialService;
import com.yunyao.dao.service.bamu.IBamuSoSupplyService;
import com.yunyao.dao.service.bamu.IBamuSpReconciliationOrderMaterialService;
import com.yunyao.dao.service.bamu.IBamuSpReconciliationOrderService;
import com.yunyao.dao.service.bamu.IBamuSpReconciliationService;
import com.yunyao.dao.service.bamu.IBamuSupplyApplyMaterialService;
import com.yunyao.dao.service.bamu.IBamuSupplyApplyService;
import com.yunyao.dao.service.bamu.IBamuSupplyConsigneeService;
import com.yunyao.framework.dto.audit.ApprovalDto;
import com.yunyao.framework.service.systemtwo.ContractService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;

;

/**
 * @author xingjishuai
 * @date 2024-08-01
 */
@Slf4j
@Component
public class ProjectOrderAuditHandle extends AbstractAuditFlowHandle {
    @Autowired
    private IBamuPurchaseApplyService iBamuPurchaseApplyService;

    @Autowired
    private IBamuSupplyApplyService iBamuSupplyApplyService;

    @Autowired
    private IBamuPurchaseApplyMaterialService iBamuPurchaseApplyMaterialService;

    @Autowired
    private IBamuSupplyApplyMaterialService iBamuSupplyApplyMaterialService;

    @Autowired
    private IBamuPurchaseConsigneeService iBamuPurchaseConsigneeService;

    @Autowired
    private IBamuSupplyConsigneeService iBamuSupplyConsigneeService;
    @Autowired
    private IBamuPoSupplyService iBamuPoSupplyService;
    @Autowired
    private IBamuPoSupplyMaterialService iBamuPoSupplyMaterialService;
    @Resource
    private ContractService contractService;
    @Resource
    private IBamuSaleContractService saleContractService;
    @Autowired
    private IBamuSoSupplyService iBamuSoSupplyService;
    @Autowired
    private IBamuSoSupplyMaterialService iBamuSoSupplyMaterialService;
    @Autowired
    private IBamuSaleContractService iBamuSaleContractService;
    @Autowired
    private IBamuReconciliationService iBamuReconciliationService;
    @Autowired
    private IBamuReconciliationOrderService iBamuReconciliationOrderService;
    @Autowired
    private IBamuReconciliationOrderMaterialService iBamuReconciliationOrderMaterialService;
    @Autowired
    private IBamuPurchaseContractService iBamuPurchaseContractService;
    @Autowired
    private IBamuSpReconciliationService iBamuSpReconciliationService;
    @Autowired
    private IBamuSpReconciliationOrderService iBamuSpReconciliationOrderService;
    @Resource
    private IBamuSoPrePaymentService prePaymentService;
    @Resource
    private IBamuPoPrePaymentService poPrePaymentService;

    @Transactional(rollbackFor = AuditException.class)
    public void submit(String bizId) throws AuditException {
        BamuPurchaseApply purchaseApply = iBamuPurchaseApplyService.getNoDeletedApplyById(bizId);
        String name = purchaseApply.getOrderSn();
        Integer status = purchaseApply.getStatus();
        String purchaseApplyId = defaultAuditModelInfo.getPurchaseApplyId();
        try {
            /**
             * 校验数据
             */
            checkSubmitData(purchaseApply);
            CreateAuditFlowDto createAuditFlowDto = creatFlow(purchaseApplyId,
                    AuditFlowTypeEnums.MODEL_NAME_PURCHASE_APPLY.getType(), bizId, name,
                    String.valueOf(status));
            purchaseApply.setProcessInstanceId(createAuditFlowDto.getProcessInstanceId());
            purchaseApply.setDeploymentId(createAuditFlowDto.getDeploymentId());
            purchaseApply.setModelSchemeInfoId(createAuditFlowDto.getModelSchemeInfoId());
            purchaseApply.setProcessVersion(createAuditFlowDto.getProcessVersion());
            purchaseApply.setAuditStatus(String.valueOf(AuditStatusEnums.AUDIT.getType()));
            purchaseApply.setFlowSubmitDate(new Date());
            iBamuPurchaseApplyService.updateById(purchaseApply);
            BamuSupplyApply supplyApply = iBamuSupplyApplyService.getByPurchaseApplyId(purchaseApply.getId());
            if (supplyApply != null) {
                supplyApply.setFlowSubmitDate(new Date());
                iBamuSupplyApplyService.saveOrUpdate(supplyApply);
            }

            //TODO 生成项目订单预付款 20241031 赵紫薇最新逻辑（注释掉）
            /*addSoPrePayment(purchaseApply).exceptionally(e -> {
                log.error("生成项目订单预付款失败!");
                return null;
            });*/
            //生成供货订单预付款
            /*addPoPrePayment(purchaseApply).exceptionally(e -> {
                log.error("生成供货订单预付款失败!");
                return null;
            });*/
        } catch (Exception e) {
            log.error("项目订单submit approval error", e);
            throw new AuditException(e.getMessage());
        }
    }

    /**
     * 电梯供货订单预付款
     * @param dto
     */
    public void addPoPrePayment(BamuPurchaseApply dto) {
/*            BamuPurchaseApply apply = iBamuPurchaseApplyService.getById(dto.getId());
            if (StringUtils.equals(apply.getContractMethod(), "0")) {
                return;
            }*/
        BamuContractNodePay nodePay = contractService.findByContractIdStatus(dto.getContractId(), "1");
        if (nodePay == null) {
            log.error("根据合同ID没有找到对应的付款节点信息,合同ID:{}", dto.getContractId());
            return;
        }

        BamuSaleContract saleContract = saleContractService.getByIdNoDelete(dto.getContractId());
        if (saleContract == null) {
            log.error("根据合同ID没有找到对应的合同信息,合同ID:{}", dto.getContractId());
            return;
        }
        UserInfoRequest userInfo = BaseContext.getUserInfo();
        BamuPoPrePayment poPrePayment = new BamuPoPrePayment();
        poPrePayment.setContractId(dto.getContractId());
        poPrePayment.setContractNo(dto.getContractNo());
        poPrePayment.setContractName(dto.getContractName());
        poPrePayment.setContractType("1");
        poPrePayment.setProjectId(dto.getProjectId());
        poPrePayment.setProjectName(dto.getProjectName());
        poPrePayment.setProjectDeptId(dto.getProjectDeptId());
        poPrePayment.setProjectDeptName(dto.getProjectDeptName());
        //项目所属地址
        poPrePayment.setProjectAddress("");
        poPrePayment.setSupplierDeptId(dto.getSupplierId());
        poPrePayment.setSupplierDeptName(dto.getSupplierName());
        // 2024/10/21供应商品类ID(暂时没有该功能)
        poPrePayment.setSupplierCategoryId("");
        //供应商品类名称为空
        poPrePayment.setSupplierCategoryName("");
        //合同预付款比例
        poPrePayment.setContractPrePaymentRate(nodePay.getBackPayRate());
        //合同预付款天数
        poPrePayment.setContractPrePaymentDay(nodePay.getNatureDay());
        //合同预付款天数类型 (没用字段)
        poPrePayment.setContractPrePaymentDayType(0);

        poPrePayment.setContractPrePaymentPrice(saleContract.getContractTotalPrice().multiply(nodePay.getBackPayRate()));
        poPrePayment.setContractPrePaymentDate(saleContract.getPaymentDeadlineDate());
        //TODO 真实付款金额
        poPrePayment.setContractRealPaymentPrice(BigDecimal.ZERO);

        poPrePayment.setContractNum(saleContract.getContractNum());
        poPrePayment.setContractTotalPrice(saleContract.getContractTotalPrice());
        poPrePayment.setContractTotalRealPrice(saleContract.getContractTotalRealPrice());
        //TODO 合同汇款总金额
        poPrePayment.setContractBackPrice(BigDecimal.ZERO);
        //项目结算单文件
        poPrePayment.setReconciliationSettlementFile("[]");
        poPrePayment.setReconciliationSettlementMark("");
        poPrePayment.setCreatedBy(userInfo.getId());
        poPrePayment.setCreateDept(userInfo.getDeptId());
        poPrePayment.setStatus(1);
        poPrePayment.setTenantId(dto.getTenantId());
        poPrePayment.setAuditStatus(dto.getAuditStatus());
        poPrePayment.setProcessInstanceId(dto.getProcessInstanceId());
        poPrePayment.setModelSchemeInfoId(dto.getModelSchemeInfoId());
        poPrePayment.setDeploymentId(dto.getDeploymentId());
        poPrePayment.setProcessVersion(dto.getProcessVersion());
        poPrePayment.setPaymentMethod("[]");
        poPrePayment.setContractMethod(dto.getContractMethod());
        poPrePayment.setPurchaseDeptId(dto.getPurchaseDeptId());
        poPrePayment.setPurchaseDeptName(dto.getPurchaseDeptName());
        poPrePayment.setCheckMark(saleContract.getMark());
        poPrePayment.setCheckFile(saleContract.getContractFile());
        poPrePayment.setOrderSn(dto.getOrderSn());
        poPrePayment.setOrderName(dto.getOrderName());
        poPrePayment.setPurchaseApplyId(dto.getPurchaseContractId());
        poPrePayment.setReceiptStatus("0");
        //TODO 回款金额
        poPrePayment.setReceivePrice(BigDecimal.ZERO);
        //TODO 结余金额
        poPrePayment.setBalanceAmount(BigDecimal.ZERO);
        poPrePaymentService.add(poPrePayment);
        log.info("电梯供货订单预付款生成成功!");
    }

    /**
     * 生成电线电缆-电梯订单预付款
     *
     * @param dto
     * @return
     */
    public void addSoPrePayment(BamuPurchaseApply dto) {
        BamuContractNodePay nodePay = contractService.findByContractIdStatus(dto.getContractId(), "1");
        if (nodePay == null) {
            log.error("根据合同ID没有找到对应的付款节点信息,合同ID:{}", dto.getContractId());
            return;
        }
        BamuSaleContract saleContract = saleContractService.getByIdNoDelete(dto.getContractId());
        if (saleContract == null) {
            log.error("根据合同ID没有找到对应的合同信息,合同ID:{}", dto.getContractId());
            return;
        }
        UserInfoRequest userInfo = BaseContext.getUserInfo();
        BamuSoPrePayment soPrePayment = new BamuSoPrePayment();
        soPrePayment.setContractId(dto.getContractId());
        soPrePayment.setContractNo(dto.getContractNo());
        soPrePayment.setContractName(dto.getContractName());
        soPrePayment.setContractType("0");
        soPrePayment.setProjectId(dto.getProjectId());
        soPrePayment.setProjectName(dto.getProjectName());
        soPrePayment.setProjectDeptId(dto.getProjectDeptId());
        soPrePayment.setProjectDeptName(dto.getProjectDeptName());
        //项目所属地址
        soPrePayment.setProjectAddress("");
        soPrePayment.setSupplierDeptId(dto.getSupplierId());
        soPrePayment.setSupplierDeptName(dto.getSupplierName());
        // 2024/10/21供应商品类ID(暂时没有该功能)
        soPrePayment.setSupplierCategoryId("");
        //供应商品类名称为空
        soPrePayment.setSupplierCategoryName("");
        //合同预付款比例
        soPrePayment.setContractPrePaymentRate(nodePay.getBackPayRate());
        //合同预付款天数
        soPrePayment.setContractPrePaymentDay(nodePay.getNatureDay());
        //合同预付款天数类型 (没用字段)
        soPrePayment.setContractPrePaymentDayType(0);

        soPrePayment.setContractPrePaymentPrice(saleContract.getContractTotalPrice().multiply(nodePay.getBackPayRate()));
        soPrePayment.setContractPrePaymentDate(saleContract.getPaymentDeadlineDate());
        //TODO 真实付款金额
        soPrePayment.setContractRealPaymentPrice(BigDecimal.ZERO);

        soPrePayment.setContractNum(saleContract.getContractNum());
        soPrePayment.setContractTotalPrice(saleContract.getContractTotalPrice());
        soPrePayment.setContractTotalRealPrice(saleContract.getContractTotalRealPrice());
        //TODO 合同汇款总金额
        soPrePayment.setContractBackPrice(BigDecimal.ZERO);
        //项目结算单文件
        soPrePayment.setReconciliationSettlementFile("[]");
        soPrePayment.setReconciliationSettlementMark("");
        soPrePayment.setCreatedBy(userInfo.getId());
        soPrePayment.setCreateDept(userInfo.getDeptId());
        soPrePayment.setStatus(1);
        soPrePayment.setTenantId(dto.getTenantId());
        soPrePayment.setAuditStatus(dto.getAuditStatus());
        soPrePayment.setProcessInstanceId(dto.getProcessInstanceId());
        soPrePayment.setModelSchemeInfoId(dto.getModelSchemeInfoId());
        soPrePayment.setDeploymentId(dto.getDeploymentId());
        soPrePayment.setProcessVersion(dto.getProcessVersion());
        soPrePayment.setPaymentMethod("[]");
        soPrePayment.setContractMethod(dto.getContractMethod());
        soPrePayment.setPurchaseDeptId(dto.getPurchaseDeptId());
        soPrePayment.setPurchaseDeptName(dto.getPurchaseDeptName());
        soPrePayment.setCheckMark(saleContract.getMark());
        soPrePayment.setCheckFile(saleContract.getContractFile());
        soPrePayment.setOrderSn(dto.getOrderSn());
        soPrePayment.setOrderName(dto.getOrderName());
        soPrePayment.setPurchaseApplyId(dto.getPurchaseContractId());
        soPrePayment.setReceiptStatus("0");
        //TODO 回款金额
        soPrePayment.setReceivePrice(BigDecimal.ZERO);
        //TODO 结余金额
        soPrePayment.setBalanceAmount(BigDecimal.ZERO);
        prePaymentService.add(soPrePayment);
    }

    public void approval(ApprovalDto approvalDto) throws AuditException {
        try {
            String bizId = approvalDto.getId();
            Boolean auditResult = approvalDto.getAuditResult();
            String auditResultStr = auditResult ? AuditResultEnums.AGREE.getKey() :
                    AuditResultEnums.REJECT.getKey();
            BamuPurchaseApply purchaseApply = iBamuPurchaseApplyService.getNoDeletedApplyById(bizId);
            checkApprovalData(purchaseApply);
            boolean isEnd = executeFlow(purchaseApply.getProcessInstanceId(),
                    purchaseApply.getDeploymentId(), auditResultStr,
                    approvalDto.getAuditResultMsg(), approvalDto.getAuditFileList());
            if (!isEnd) {
                return;
            }
            BamuSupplyApply supplyApply = iBamuSupplyApplyService.getByPurchaseApplyId(purchaseApply.getId());
            if (auditResult) {
                purchaseApply.setAuditStatus(String.valueOf(AuditStatusEnums.AUDIT_SUCCESS.getType()));
                purchaseApply.setSupplyStatus(SupplyStatus.SUPPLIER_AWAITING_CONFIRMATION.getType());

                if (supplyApply != null) {
                    supplyApply.setAuditStatus(String.valueOf(AuditStatusEnums.AUDIT_SUCCESS.getType()));
                    supplyApply.setSupplyStatus(SupplyStatus.SUPPLIER_AWAITING_CONFIRMATION.getType());
                }
                //创建供货订单
                createOrder(purchaseApply);
                //
                //生成电线电缆订单预付款   20241031 赵紫薇最新逻辑
                addSoPrePayment(purchaseApply);
                //电梯供货订单预付款
                addPoPrePayment(purchaseApply);

            } else {
                purchaseApply.setAuditStatus(String.valueOf(AuditStatusEnums.AUDIT_REJECT.getType()));
                if (supplyApply != null) {
                    supplyApply.setAuditStatus(String.valueOf(AuditStatusEnums.AUDIT_REJECT.getType()));
                }
            }
            iBamuPurchaseApplyService.updateById(purchaseApply);
            if (supplyApply != null) {
                iBamuSupplyApplyService.updateById(supplyApply);
            }
        } catch (Exception e) {
            log.error("销售合同 approval error", e);
            throw new AuditException(e.getMessage());
        }

    }

    /**
     * 创建供货订单
     *
     * @param
     */
    @Transactional(rollbackFor = Exception.class)
    public void createOrder(BamuPurchaseApply purchaseApply) {
        BamuPurchaseApply apply = iBamuPurchaseApplyService.getById(purchaseApply.getId());
        if (StringUtils.equals(apply.getContractMethod(), "1")) {
            return;
        }
        BamuSupplyApply supply = iBamuSupplyApplyService.getByPurchaseApplyId(purchaseApply.getId());
        if (supply != null) {
            log.warn("供货订单已存在");
            return;
        }
        createSupplyApply(apply);
    }

    private BamuPoSupply createPoSupplyApply(BamuSupplyApply supply) {
        String contractId = supply.getContractId();
        BamuPurchaseContract bamuPurchaseContract = iBamuPurchaseContractService.getBySaleContractId(contractId);
        BamuPoSupply bamuPoSupply = new BamuPoSupply();
        BeanUtils.copyProperties(supply, bamuPoSupply);
        bamuPoSupply.setId(null);
        bamuPoSupply.setShipmentAt(new Date());
        bamuPoSupply.setApplyId(supply.getId());
        bamuPoSupply.setShipmentDesc("自动供货完成");
        bamuPoSupply.setSupplyStatus(SupplyListStatus.PROJECT_ACCEPTANCE_COMPLETED.getType());
        bamuPoSupply.setContractId(bamuPurchaseContract.getId());
        bamuPoSupply.setContractName(bamuPurchaseContract.getContractName());
        bamuPoSupply.setProjectId(bamuPurchaseContract.getProjectId());
        bamuPoSupply.setProjectName(bamuPurchaseContract.getProjectName());
        bamuPoSupply.setPurchaseDeptId(bamuPurchaseContract.getPurchaseDeptId());
        bamuPoSupply.setPurchaseDeptName(bamuPurchaseContract.getPurchaseDeptName());
        bamuPoSupply.setSaleDeptId(bamuPurchaseContract.getProjectDeptId());
        bamuPoSupply.setSaleDeptName(bamuPurchaseContract.getProjectDeptName());
        bamuPoSupply.setProjectDeptId(bamuPurchaseContract.getProjectDeptId());
        bamuPoSupply.setProjectDeptName(bamuPurchaseContract.getProjectDeptName());
        iBamuPoSupplyService.saveOrUpdate(bamuPoSupply);
        List<BamuSupplyApplyMaterial> materialList = iBamuSupplyApplyMaterialService.listByPurchaseApplyId(supply.getId());
        if (CollectionUtils.isNotEmpty(materialList)) {
            ArrayList<BamuPoSupplyMaterial> poSupplyMaterials = new ArrayList<>();
            for (BamuSupplyApplyMaterial bamuSupplyApplyMaterial : materialList) {
                BamuPoSupplyMaterial poSupplyMaterial = new BamuPoSupplyMaterial();
                BeanUtils.copyProperties(bamuSupplyApplyMaterial, poSupplyMaterial);
                // 这里可以添加其他必要的属性设置
                poSupplyMaterial.setId(null);
                // 关联到BamuPoSupply
                poSupplyMaterial.setSupplyId(bamuPoSupply.getId());
                // 设置材料ID
                poSupplyMaterial.setMaterialId(bamuSupplyApplyMaterial.getMaterialId());
                poSupplyMaterial.setPurchaseApplyId(bamuPoSupply.getApplyId());
                poSupplyMaterial.setOrderMaterialId(bamuSupplyApplyMaterial.getOrderMaterialId());
                poSupplyMaterials.add(poSupplyMaterial);
            }
            iBamuPoSupplyMaterialService.saveBatch(poSupplyMaterials);
        }
        return bamuPoSupply;
    }

    private void createSupplyApply(BamuPurchaseApply apply) {
        String purchaseApplyId = apply.getId();
        /**
         * 项目订单审核成功，生成供货订单
         */
        BamuSupplyApply supply = new BamuSupplyApply();
        BeanUtils.copyProperties(apply, supply);
        supply.setId(null);
        supply.setApplyId(apply.getId());
        supply.setAuditStatus(AuditStatusEnums.AUDIT_SUCCESS.getType().toString());
        supply.setCopperDate(apply.getCopperDate());
        supply.setSupplyStatus(SupplyStatus.SUPPLY_COMPLETED.getType());
        supply.setFlowSubmitDate(apply.getFlowSubmitDate());
        iBamuSupplyApplyService.save(supply);
        LambdaQueryWrapper<BamuPurchaseApplyMaterial> materialLambdaQueryWrapper = new LambdaQueryWrapper<>();
        materialLambdaQueryWrapper.eq(BamuPurchaseApplyMaterial::getPurchaseApplyId, purchaseApplyId).eq(BamuPurchaseApplyMaterial::getIsDeleted, DataDeletedStatus.NO.getType());
        List<BamuPurchaseApplyMaterial> purchaseApplyMaterialList = iBamuPurchaseApplyMaterialService.list(materialLambdaQueryWrapper);
        if (CollectionUtils.isNotEmpty(purchaseApplyMaterialList)) {
            /**
             * 保存供货订单材料
             */
            List<BamuSupplyApplyMaterial> saveMaterialList = new ArrayList<>();
            for (BamuPurchaseApplyMaterial purchaseApplyMaterial : purchaseApplyMaterialList) {
                BamuSupplyApplyMaterial supplyApplyMaterial = new BamuSupplyApplyMaterial();
                BeanUtils.copyProperties(purchaseApplyMaterial, supplyApplyMaterial);
                supplyApplyMaterial.setId(null);
                supplyApplyMaterial.setPurchaseApplyId(supply.getId());
                supplyApplyMaterial.setOrderMaterialId(purchaseApplyMaterial.getId());
                supplyApplyMaterial.setIncludingTaxUnitPrice(purchaseApplyMaterial.getIncludingTaxUnitPrice());
                saveMaterialList.add(supplyApplyMaterial);
            }
            iBamuSupplyApplyMaterialService.saveBatch(saveMaterialList);
        }
        LambdaQueryWrapper<BamuPurchaseConsignee> consigneeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        consigneeLambdaQueryWrapper.eq(BamuPurchaseConsignee::getPurchaseApplyId, purchaseApplyId).eq(BamuPurchaseConsignee::getIsDeleted, DataDeletedStatus.NO.getType());
        List<BamuPurchaseConsignee> purchaseConsigneeList = iBamuPurchaseConsigneeService.list(consigneeLambdaQueryWrapper);
        List<BamuSupplyConsignee> saveConsigneeList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(purchaseConsigneeList)) {
            for (BamuPurchaseConsignee purchaseConsignee : purchaseConsigneeList) {
                BamuSupplyConsignee supplyConsignee = new BamuSupplyConsignee();
                BeanUtils.copyProperties(purchaseConsignee, supplyConsignee);
                supplyConsignee.setPurchaseApplyId(supply.getId());
                supplyConsignee.setId(null);
                saveConsigneeList.add(supplyConsignee);
            }
            iBamuSupplyConsigneeService.saveBatch(saveConsigneeList);
        }
        BamuPoSupply poSupply = createPoSupplyApply(supply);
        BamuSoSupply soSupply = createSoSupply(poSupply, apply);
        createReconciliation(soSupply);
        createSpReconciliation(poSupply);
    }

    private BamuSpReconciliation createSpReconciliation(BamuPoSupply poSupply) {
        String contractId = poSupply.getContractId();
        BamuSpReconciliation reconciliation = new BamuSpReconciliation();
        BamuPurchaseContract purchaseContract = iBamuPurchaseContractService.getByIdNoDelete(contractId);
        if (Objects.isNull(purchaseContract)) {
            return null;
        }
        reconciliation.setContractId(contractId);
        reconciliation.setContractNo(purchaseContract.getContractNo());
        reconciliation.setContractName(purchaseContract.getContractName());
        reconciliation.setPurchaseDeptId(purchaseContract.getPurchaseDeptId());
        reconciliation.setPurchaseDeptName(purchaseContract.getPurchaseDeptName());
        reconciliation.setPurchaseDeptName(purchaseContract.getPurchaseDeptName());
        reconciliation.setProjectId(purchaseContract.getProjectId());
        reconciliation.setProjectName(purchaseContract.getProjectName());
        reconciliation.setSupplyDeptId(purchaseContract.getSupplyDeptId());
        reconciliation.setSupplyDeptName(purchaseContract.getSupplyDeptName());
        reconciliation.setSupplierDeptId(purchaseContract.getSupplierDeptId());
        reconciliation.setSupplierDeptName(purchaseContract.getSupplierDeptName());
        reconciliation.setContractMethod(purchaseContract.getContractMethod());
        reconciliation.setProjectDeptId(purchaseContract.getProjectDeptId());
        reconciliation.setProjectDeptName(purchaseContract.getProjectDeptName());
        reconciliation.setContractRebatePoints(purchaseContract.getContractRebatePoints());
        BigDecimal contractRebatePoints = purchaseContract.getContractRebatePoints();
        BigDecimal contractTotalRealPrice = purchaseContract.getContractTotalRealPrice();
        if (Objects.nonNull(contractRebatePoints) && Objects.nonNull(contractTotalRealPrice)
                && contractRebatePoints.doubleValue() > BigDecimal.ZERO.doubleValue() && contractTotalRealPrice.doubleValue() > BigDecimal.ZERO.doubleValue()) {
            reconciliation.setContractRebatePrice(contractRebatePoints.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).multiply(contractTotalRealPrice));
        }
        // 解析并设置对账开始日期
        reconciliation.setReconciliationStartDate(new Date());
        // 解析并设置对账结束日期
        reconciliation.setReconciliationEndDate(new Date());
        reconciliation.setStatus(12);
        reconciliation.setSupplyNum(BigDecimal.ONE.intValue());
        reconciliation.setReconciliationNum(BigDecimal.ONE);
        reconciliation.setSupplyIncludingTaxTotalPrice(poSupply.getTaxTotalPrice());
        reconciliation.setReconciliationPrice(poSupply.getTaxTotalPrice());
        // 保存或更新结算信息
        iBamuSpReconciliationService.saveOrUpdate(reconciliation);
        // 初始化一个新的结算单对象
        BamuSpReconciliationOrder spReconciliationOrder =
                new BamuSpReconciliationOrder();
        // 复制对账结果的属性到结算单对象
        BeanUtils.copyProperties(poSupply, spReconciliationOrder);
        // 设置结算单的唯一ID
        spReconciliationOrder.setReconciliationId(reconciliation.getId());
        // 保留原对账单的ID
        spReconciliationOrder.setSupplyId(poSupply.getId());
        // 将结算单对象的ID设置为null，标记这是一个新的记录
        spReconciliationOrder.setId(null);
        iBamuSpReconciliationOrderService.save(spReconciliationOrder);
        List<BamuSoSupplyMaterial> poSupplyMaterialList =
                iBamuSoSupplyMaterialService.listByReconciliationId(poSupply.getId());
        if (CollectionUtils.isNotEmpty(poSupplyMaterialList)) {
            List<BamuReconciliationOrderMaterial> reconciliationOrderMaterialList =
                    new ArrayList<>();
            for (BamuSoSupplyMaterial soSupplyMaterial : poSupplyMaterialList) {
                BamuReconciliationOrderMaterial reconciliationOrderMaterial =
                        new BamuReconciliationOrderMaterial();
                BeanUtils.copyProperties(soSupplyMaterial, reconciliationOrderMaterial);
                reconciliationOrderMaterial.setReconciliationNum(soSupplyMaterial.getComfirmSupplyNum());
                reconciliationOrderMaterial.setReconciliationPrice(soSupplyMaterial.getIncludingTaxTotalPrice());
                // 设置结算单ID
                reconciliationOrderMaterial.setReconciliationId(reconciliation.getId());
                // 设置结算单项ID
                reconciliationOrderMaterial.setReconciliationOrderId(spReconciliationOrder.getId());
                reconciliationOrderMaterial.setReconciliationOrderSn(poSupply.getOrderSn());
                // 为新生成的结算单材料对象设置一个空的ID，表示它是一个新对象
                reconciliationOrderMaterial.setId(null);
            }
            iBamuReconciliationOrderMaterialService.saveBatch(reconciliationOrderMaterialList);
        }
        return reconciliation;
    }

    private BamuReconciliation createReconciliation(BamuSoSupply soSupply) {
        String contractId = soSupply.getContractId();
        BamuReconciliation reconciliation = new BamuReconciliation();
        // 解析并设置对账开始日期
        reconciliation.setReconciliationStartDate(new Date());
        // 解析并设置对账结束日期
        reconciliation.setReconciliationEndDate(new Date());
        reconciliation.setStatus(12);
        reconciliation.setAuditStatus("2");
        reconciliation.setCreateStatus("1");
        BamuSaleContract saleContract = iBamuSaleContractService.getByIdNoDelete(contractId);
        if (Objects.isNull(saleContract)) {
            return null;
        }
        reconciliation.setContractId(contractId);
        reconciliation.setContractNo(saleContract.getContractNo());
        reconciliation.setContractName(saleContract.getContractName());
        reconciliation.setPurchaseDeptId(saleContract.getPurchaseDeptId());
        reconciliation.setPurchaseDeptName(saleContract.getPurchaseDeptName());
        reconciliation.setPurchaseDeptName(saleContract.getPurchaseDeptName());
        reconciliation.setProjectId(saleContract.getProjectId());
        reconciliation.setProjectName(saleContract.getProjectName());
        reconciliation.setSupplyDeptId(saleContract.getSupplyDeptId());
        reconciliation.setSupplyDeptName(saleContract.getSupplyDeptName());
        reconciliation.setSupplierDeptId(saleContract.getSupplierDeptId());
        reconciliation.setSupplierDeptName(saleContract.getSupplierDeptName());
        reconciliation.setContractMethod(saleContract.getContractMethod());
        reconciliation.setProjectDeptId(saleContract.getProjectDeptId());
        reconciliation.setProjectDeptName(saleContract.getProjectDeptName());
        reconciliation.setSupplyNum(BigDecimal.ONE.intValue());
        reconciliation.setReconciliationNum(BigDecimal.ONE);
        reconciliation.setSupplyIncludingTaxTotalPrice(soSupply.getTaxTotalPrice());
        reconciliation.setReconciliationPrice(soSupply.getTaxTotalPrice());
        // 保存或更新结算信息
        iBamuReconciliationService.saveOrUpdate(reconciliation);
        // 初始化一个新的结算单对象
        BamuReconciliationOrder bamuReconciliationOrder =
                new BamuReconciliationOrder();
        // 复制对账结果的属性到结算单对象
        BeanUtils.copyProperties(soSupply, bamuReconciliationOrder);
        // 设置结算单的唯一ID
        bamuReconciliationOrder.setReconciliationId(reconciliation.getId());
        // 保留原对账单的ID
        bamuReconciliationOrder.setSupplyId(soSupply.getId());
        // 将结算单对象的ID设置为null，标记这是一个新的记录
        bamuReconciliationOrder.setId(null);
        iBamuReconciliationOrderService.save(bamuReconciliationOrder);
        List<BamuSoSupplyMaterial> poSupplyMaterialList =
                iBamuSoSupplyMaterialService.listByReconciliationId(soSupply.getId());
        if (CollectionUtils.isNotEmpty(poSupplyMaterialList)) {
            List<BamuReconciliationOrderMaterial> reconciliationOrderMaterialList =
                    new ArrayList<>();
            for (BamuSoSupplyMaterial soSupplyMaterial : poSupplyMaterialList) {
                BamuReconciliationOrderMaterial reconciliationOrderMaterial =
                        new BamuReconciliationOrderMaterial();
                BeanUtils.copyProperties(soSupplyMaterial, reconciliationOrderMaterial);
                reconciliationOrderMaterial.setReconciliationNum(soSupplyMaterial.getComfirmSupplyNum());
                reconciliationOrderMaterial.setReconciliationPrice(soSupplyMaterial.getIncludingTaxTotalPrice());
                // 设置结算单ID
                reconciliationOrderMaterial.setReconciliationId(reconciliation.getId());
                // 设置结算单项ID
                reconciliationOrderMaterial.setReconciliationOrderId(bamuReconciliationOrder.getId());
                reconciliationOrderMaterial.setReconciliationOrderSn(soSupply.getOrderSn());
                // 为新生成的结算单材料对象设置一个空的ID，表示它是一个新对象
                reconciliationOrderMaterial.setId(null);
            }
            iBamuReconciliationOrderMaterialService.saveBatch(reconciliationOrderMaterialList);
        }
        return reconciliation;
    }

    private BamuSoSupply createSoSupply(BamuPoSupply poSupply, BamuPurchaseApply purchaseApply) {
        BamuSoSupply bamuSoSupply = new BamuSoSupply();
        BeanUtils.copyProperties(poSupply, bamuSoSupply);
        bamuSoSupply.setId(null);
        bamuSoSupply.setShipmentAt(new Date());
        bamuSoSupply.setShipmentDesc("自动供货");
        bamuSoSupply.setPoSupplyId(poSupply.getId());
        bamuSoSupply.setApplyId(purchaseApply.getId());
        bamuSoSupply.setSupplyStatus(SupplyListStatus.PROJECT_ACCEPTANCE_COMPLETED.getType());
        bamuSoSupply.setContractId(purchaseApply.getContractId());
        bamuSoSupply.setContractName(purchaseApply.getContractName());
        iBamuSoSupplyService.saveOrUpdate(bamuSoSupply);
        List<BamuPoSupplyMaterial> poSupplyMaterialList =
                iBamuPoSupplyMaterialService.listBySupplyId(poSupply.getId());
        if (CollectionUtils.isNotEmpty(poSupplyMaterialList)) {
            List<BamuSoSupplyMaterial> soSupplyMaterialList = new ArrayList<>();
            for (BamuPoSupplyMaterial poSupplyMaterial : poSupplyMaterialList) {
                BamuSoSupplyMaterial soSupplyMaterial = new BamuSoSupplyMaterial();
                BeanUtils.copyProperties(poSupplyMaterial, soSupplyMaterial);
                soSupplyMaterial.setId(null);
                soSupplyMaterial.setSupplyId(bamuSoSupply.getId());
                soSupplyMaterial.setMaterialId(poSupplyMaterial.getMaterialId()); // 设置材料ID
                soSupplyMaterial.setPoSupplyMaterialId(poSupplyMaterial.getId());
                soSupplyMaterial.setPurchaseApplyId(bamuSoSupply.getApplyId());
                soSupplyMaterialList.add(soSupplyMaterial);
            }
            iBamuSoSupplyMaterialService.saveBatch(soSupplyMaterialList);
        }
        return bamuSoSupply;
    }

    private void checkApprovalData(BamuPurchaseApply purchaseApply) throws AuditException {
        if (Objects.isNull(purchaseApply)) {
            throw new AuditException(ResultMsgEnum.NO_DATA);
        }
        String auditStatus = purchaseApply.getAuditStatus();
        if (AuditStatusEnums.AUDIT.getType() != Integer.parseInt(auditStatus)) {
            throw new AuditException(ResultMsgEnum.SUBMIT_AUDIT_STATUS_ERROR);
        }
        String processInstanceId = purchaseApply.getProcessInstanceId();
        if (StringUtils.isBlank(processInstanceId)) {
            throw new AuditException("processInstanceId is null");
        }
        String deploymentId = purchaseApply.getDeploymentId();
        if (StringUtils.isBlank(deploymentId)) {
            throw new AuditException("deploymentId is null");
        }
    }

    public boolean userIsAuditButton(String schemeInfoId, String processInstanceId) {
        try {
            return isCheckAudit(schemeInfoId, processInstanceId);
        } catch (Exception e) {
            log.info("项目订单userIsAuditButton error:{}", e.getMessage());
            return false;
        }
    }

    private void checkSubmitData(BamuPurchaseApply purchaseApply) throws AuditException {

        if (Objects.isNull(purchaseApply)) {
            throw new AuditException(ResultMsgEnum.NO_DATA);
        }

        String auditStatus = purchaseApply.getAuditStatus();
        if (AuditStatusEnums.AUDIT.getType() == Integer.parseInt(auditStatus)
                && AuditStatusEnums.AUDIT_SUCCESS.getType() == Integer.parseInt(auditStatus)
                && AuditStatusEnums.AUDIT_REJECT.getType() == Integer.parseInt(auditStatus)) {
            throw new AuditException(ResultMsgEnum.SUBMIT_AUDIT_STATUS_ERROR);
        }
    }
}
